package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.DataManager;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.AbsSameTimeRoom;

/**
 * 天秤座连珠
 * 江柯版本同时制五子棋：
 * 落子后形成活五数量多的一方获胜。
 * 若形成活五数量相同，落子位置变为墙。
 * 双方落子在相同的位置也会变成墙。
 * 若双方落子后没有形成墙，那么所有墙都消失。
 */
public class LibraSameTimeGoBangRoom extends AbsSameTimeRoom {

    public LibraSameTimeGoBangRoom(String roomName) {
        super(roomName, "江柯设计的同步五子棋规则，进攻靠技术，防御看运气，非常的刺激！", "天秤座连珠", BoardStyleData.getGoBangStyle(12, 12), false, true, "活4", "活3");
        setForbidChat(true);
    }

    @Override
    public String getRuleText() {
        return "《天秤座连珠》\n" +
                "黑白双方同时在棋盘空格上落子,然后结算;\n" +
                "若双方落在了相同的位置，则该位置变成墙;\n" +
                "双方落在了不同位置时，判断形成五连珠的数量;\n" +
                "同一条线上超过五颗棋子的也只算做一个五连珠;\n" +
                "不在同一条线上但是共用了相同棋子的可以都算作五连珠;\n" +
                "若双方形成五连珠的数量相同，则双方落点位置都变成墙;\n" +
                "形成五连珠数量大的一方获得胜利;\n" +
                "若都没有形成五连珠，则所有墙都会消失。";
    }

    @Override
    protected void onStartPrepare() {
        noticeAllMove();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        //因为获胜判断时展示了比分，所以这里要还原隐藏
        blackScore = -1;
        whiteScore = -1;
    }

    @Override
    public void doSameTimeRule(int blackRow, int blackCol, int blackValue, int whiteRow, int whiteCol, int whiteValue) {
        if (blackRow == whiteRow && blackCol == whiteCol) {
            curGrids[blackRow][whiteCol] = 9; //双方落子位置相同，相同的地方变成墙
            noticeAllMove();
            addHistory(); //添加历史记录
        }
        else {
            curGrids[blackRow][blackCol] = blackValue;
            curGrids[whiteRow][whiteCol] = whiteValue;
            int lengthB = checkFormationB(1);
            int lengthW = checkFormationB(2);
            boolean isBW = lengthB > 0;
            boolean isWW = lengthW > 0;
            if (isBW && isWW) {
                if (lengthB > lengthW) {
                    blackScore = lengthB;
                    whiteScore = lengthW;
                    addHistory(); //添加历史记录
                    doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                }
                else if (lengthW > lengthB) {
                    blackScore = lengthB;
                    whiteScore = lengthW;
                    addHistory(); //添加历史记录
                    doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                }
                else { //同时连五长度相同都变成墙
                    curGrids[blackRow][blackCol] = 9;
                    curGrids[whiteRow][whiteCol] = 9;
                    noticeAllMove();
                    addHistory(); //添加历史记录
                }
            }
            else if (isBW) {
                blackScore = lengthB;
                whiteScore = lengthW;
                addHistory(); //添加历史记录
                doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
            }
            else if (isWW) {
                blackScore = lengthB;
                whiteScore = lengthW;
                addHistory(); //添加历史记录
                doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
            }
            else { //没有继续变墙，则所有墙都消失
                clearWalls();
                noticeAllMove();
                addHistory(); //添加历史记录
            }
        }
    }

    private void clearWalls() {
        int rs = curGrids.length;
        int cs = curGrids[0].length;
        for (int i = 0; i < rs; i++) {
            for (int j = 0; j < cs; j++) {
                int v = curGrids[i][j];
                if (v == 9) {
                    curGrids[i][j] = 0;
                }
            }
        }
    }

    //获取成5的次数 （长连算多个）
    private int checkFormation(int value) {
        int rows = curGrids.length;
        int cols = curGrids[0].length;
        int formationCount = 0;

        // 水平方向
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols - 4; j++) {
                int length = 0;
                for (int k = j; k < j + 5; k++) {
                    if (curGrids[i][k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 垂直方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 0; j < cols; j++) {
                int length = 0;
                for (int k = i; k < i + 5; k++) {
                    if (curGrids[k][j] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 左上到右下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 0; j < cols - 4; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j + k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 右上到左下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 4; j < cols; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j - k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        return formationCount;
    }

    //获取成5的次数 （长连只算一个）（非通用，本棋特点，一行内只会出现一个连五才能这样写）
    private int checkFormationB(int value) {
        int live = 5; //默认活5
        if (isCurMode("活4")) live = 4;
        else if (isCurMode("活3")) live = 3;
        int liveS = live - 1;

        int rows = curGrids.length;
        int cols = curGrids[0].length;
        int formationCount = 0;

        // 水平方向
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols - liveS; j++) {
                int length = 0;
                for (int k = j; k < j + live; k++) {
                    if (curGrids[i][k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= live) {
                    formationCount += 1;
                    break;
                }
            }
        }

        // 垂直方向
        for (int i = 0; i < rows - liveS; i++) {
            for (int j = 0; j < cols; j++) {
                int length = 0;
                for (int k = i; k < i + live; k++) {
                    if (curGrids[k][j] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= live) {
                    formationCount += 1;
                    break;
                }
            }
        }

        // 左上到右下方向
        for (int i = 0; i < rows - liveS; i++) {
            for (int j = 0; j < cols - liveS; j++) {
                int length = 0;
                for (int k = 0; k < live; k++) {
                    if (curGrids[i + k][j + k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= live) {
                    formationCount += 1;
                    break;
                }
            }
        }

        // 右上到左下方向
        for (int i = 0; i < rows - liveS; i++) {
            for (int j = liveS; j < cols; j++) {
                int length = 0;
                for (int k = 0; k < live; k++) {
                    if (curGrids[i + k][j - k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= live) {
                    formationCount += 1;
                    break;
                }
            }
        }

        return formationCount;
    }
}
